//
//  TYZNetworkAgent.m
//  DrivieSchoolStudents
//
//  Created by TangBin on 2019/5/29.
//  Copyright © 2019 班文政. All rights reserved.
//

#import "TYZNetworkAgent.h"
#import "TYZNetworkConfig.h"
#import <pthread/pthread.h>
#import <AFNetworking/AFNetworking.h>
#import "TYZBaseRequest.h"
#import "TYZNetworkPrivate.h"


#define kTYZNetworkIncompleteDownloadFolderName @"Incomplete"

@interface TYZNetworkAgent ()
{
    dispatch_queue_t _processingQueue;
    pthread_mutex_t _lock;
    NSIndexSet *_allStatusCodes;
}
@property (nonatomic, strong) TYZNetworkConfig *config;
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@property (nonatomic, strong) AFJSONResponseSerializer *jsonResponseSerializer;
@property (nonatomic, strong) AFXMLParserResponseSerializer *xmlParserResponseSerialzier;
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, TYZBaseRequest *> *requestsRecord;

- (void)setupData;

@end

@implementation TYZNetworkAgent

+ (instancetype)sharedInstance
{
    static id insance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        insance = [[self alloc] init];
    });
    return insance;
}

- (instancetype)init
{
    if (self = [super init])
    {
        [self setupData];
    }
    return self;
}

/**
 初始化
 */
- (void)setupData
{
    _config = [TYZNetworkConfig sharedConfig]; // 全局配置
    _manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:_config.sessionConfiguration];
    _manager.requestSerializer.timeoutInterval = 30;
    _requestsRecord = [[NSMutableDictionary alloc] initWithCapacity:0];
    
    // 并行队列
    _processingQueue = dispatch_queue_create("com.tb.network.process", DISPATCH_QUEUE_CONCURRENT);
    
    _allStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(100, 500)];
    
    pthread_mutex_init(&_lock, NULL);
    
    // 安全策略
    _manager.securityPolicy = _config.securityPolicy;
    
    // 响应报文序列化的方式
    _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 接管状态代码验证
    _manager.responseSerializer.acceptableStatusCodes = _allStatusCodes;
    
    _manager.completionQueue = _processingQueue;
    
}

/**
 添加请求
 
 @param request request description
 */
- (void)addRequest:(TYZBaseRequest *)request
{
    NSParameterAssert(request != nil);
    
    NSError * __autoreleasing requestSerializationError = nil;
    
    // 用户可能会自定义NSURLRequest
    NSURLRequest *customRequest = [request buildCustomUrlRequest];
    if (customRequest)
    {// 如果是自定义，就直接发起网络请求
        __block NSURLSessionDataTask *dataTask = nil;
        dataTask = [_manager dataTaskWithRequest:customRequest uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            [self handleRequestResult:dataTask responseObject:responseObject error:error];
        }];
        request.requestTask = dataTask;
    }
    else
    {
        request.requestTask = [self sessionTaskForRequest:request error:&requestSerializationError];
    }
    
    if (requestSerializationError)
    {
        [self requestDidFailWithRequest:request error:requestSerializationError];
        return;
    }
    
    NSAssert(request.requestTask != nil, @"requestTask should not be nil.");
    
    // 优先级处理 ios 8 + 可用
    if ([request.requestTask respondsToSelector:@selector(priority)])
    {
        switch (request.requestPriority)
        {
            case TYZRequestPriorityHigh:
            {
                request.requestTask.priority = NSURLSessionTaskPriorityHigh;
            } break;
            case TYZRequestPriorityLow:
            {
                request.requestTask.priority = NSURLSessionTaskPriorityLow;
            } break;
            default:
            {
                request.requestTask.priority = NSURLSessionTaskPriorityDefault;
            } break;
        }
    }
    
    [self addRequestToRecord:request]; //  添加到字典中
    [request.requestTask resume];
}

/**
 取消请求
 
 @param request request description
 */
- (void)cancelRequest:(TYZBaseRequest *)request
{
    NSParameterAssert(request != nil);
    if (request.resumableDownloadPath)
    {
        NSURLSessionDownloadTask *requestTask = (NSURLSessionDownloadTask *)request.requestTask;
        [requestTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
            NSURL *localUrl = [self incompleteDownloadTempPathForDownloadPath:request.resumableDownloadPath];
            [resumeData writeToURL:localUrl atomically:YES];
        }];
    }
    else
    {
        [request.requestTask cancel];
    }
    [self removeRequestFromRecord:request]; // 从字典中删除
    [request clearCompletionBlock]; // 把block清空
}

/**
 取消所有请求
 */
- (void)cancelAllRequests
{
    pthread_mutex_lock(&_lock);
    NSArray *allKeys = [_requestsRecord allKeys];
    pthread_mutex_unlock(&_lock);
    
    if (allKeys && allKeys.count > 0)
    {
        NSArray *copiedKeys = [allKeys copy];
        for (NSNumber *key in copiedKeys)
        {
            pthread_mutex_lock(&_lock);
            TYZBaseRequest *request = _requestsRecord[key];
            pthread_mutex_unlock(&_lock);
            [request stop];
        }
    }
}

/**
 得到请求的请求地址url
 
 @param request request description
 @return return value description
 */
- (NSString *)buildRequestUrl:(TYZBaseRequest *)request
{
    NSParameterAssert(request != nil); // request 不能为nil
    
    // 获取详细URL，这个是调用者自己实现的
    NSString *detailUrl = [request requestUrl]; // 请求地址的后半部分 也可以是完整的地址
    
    NSURL *temp = [NSURL URLWithString:detailUrl];
    
    // 判断当前的detailURL 是不是一个完成的URl
    if (temp && temp.host && temp.scheme)
    {// 是完整的地址
        return detailUrl;
    }
    
    // filter url if needed
    NSArray *filters = [_config urlFilters];
    for (id<TYZUrlFilterProtocol> fl in filters)
    {
        detailUrl = [fl filterUrl:detailUrl request:request];
    }
    
    // 设置当前的baseUrl
    NSString *baseUrl;
    if ([request baseUrl].length > 0)
    {// 如果有具体的个别设置，就先用这个
        baseUrl = [request baseUrl];
    }
    else
    {// 否则使用全局配置
        baseUrl = [_config baseUrl];
    }
    
    NSURL *url = [NSURL URLWithString:baseUrl];
    if (baseUrl.length > 0 && ![baseUrl hasSuffix:@"/"])
    {
        url = [url URLByAppendingPathComponent:@""];
    }
    
    return [NSString stringWithFormat:@"%@%@",url,detailUrl];
//    NSLog(@"%@",[NSURL URLWithString:detailUrl relativeToURL:url].absoluteString);
//    return [NSURL URLWithString:detailUrl relativeToURL:url].absoluteString;
}

#pragma mark - setter getter
- (AFJSONResponseSerializer *)jsonResponseSerializer
{
    if (!_jsonResponseSerializer)
    {
        _jsonResponseSerializer = [AFJSONResponseSerializer serializer];
        _jsonResponseSerializer.acceptableStatusCodes = _allStatusCodes;
    }
    return _jsonResponseSerializer;
}

- (AFXMLParserResponseSerializer *)xmlParserResponseSerialzier
{
    if (!_xmlParserResponseSerialzier)
    {
        _xmlParserResponseSerialzier = [AFXMLParserResponseSerializer serializer];
        _xmlParserResponseSerialzier.acceptableStatusCodes = _allStatusCodes;
    }
    return _xmlParserResponseSerialzier;
}

#pragma mark - private methods
/**
 设置request的请求的数据格式、超时时间、请求的头等参数设置

 @param request request description
 @return return value description
 */
- (AFHTTPRequestSerializer *)requestSerializerForRequest:(TYZBaseRequest *)request
{
    AFHTTPRequestSerializer *requestSerializer = nil;
    // 设置请求的数据格式
    if (request.requestSerializerType == TYZRequestSerializerTypeHTTP)
    {
        requestSerializer = [AFHTTPRequestSerializer serializer];
    }
    else if (request.requestSerializerType == TYZRequestSerializerTypeJSON)
    {
        requestSerializer = [AFJSONRequestSerializer serializer];
    }
    
    requestSerializer.timeoutInterval = [request requestTimeoutInterval];
    requestSerializer.allowsCellularAccess = [request allowsCellularAccess];
//    NSLog(@"allowsCellularAccess=%d", [requestSerializer allowsCellularAccess]);
    // if api needs server username and password
    NSArray<NSString *> *authorizationHeaderFieldArray = [request requestAuthorizationHeaderFieldArray];
    if (authorizationHeaderFieldArray != nil)
    {
        [requestSerializer setAuthorizationHeaderFieldWithUsername:authorizationHeaderFieldArray.firstObject password:authorizationHeaderFieldArray.lastObject];
    }
    
    // http header field
    NSDictionary<NSString *, NSString *> *headerDict = [request requestHeaderFieldValueDictionary];
    if (headerDict)
    {
        [headerDict enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
            [requestSerializer setValue:obj forHTTPHeaderField:key];
        }];
    }
    
    return requestSerializer;
}

- (NSURLSessionTask *)sessionTaskForRequest:(TYZBaseRequest *)request error:(NSError *_Nullable __autoreleasing *)error
{
    // 得到Method
    TYZRequestMethod method = [request requestMethod];
    // 得到请求的地址
    NSString *url = [self buildRequestUrl:request];
    // 得到请求的参数
    id param = [request requestArgument];
//    NSLog(@"请求参数:%@", param);
//    NSLog(@"url=%@; method=%d", url, method);
    
    // 拼接当前的多表单
    AFConstructingBlock constructingBlock = [request constructingBodyBlock];
    AFHTTPRequestSerializer *requestSerializer = [self requestSerializerForRequest:request];
    switch (method)
    {
        case TYZRequestMethodGET:
        {
            if (request.resumableDownloadPath)
            {
                return [self downloadTaskWithDownloadPath:request.resumableDownloadPath requestSerializer:requestSerializer URLString:url parameters:param progress:request.resumableDownloadProgressBlock error:error];
            }
            else
            {
                return [self dataTaskWithHTTPMethod:@"GET" requestSerializer:requestSerializer URLString:url parameters:param error:error];
            }
        } break;
        case TYZRequestMethodPOST:
        {
            return [self dataTaskWithHTTPMethod:@"POST" requestSerializer:requestSerializer URLString:url parameters:param constructingBodyWithBlock:constructingBlock error:error];
        } break;
        default:
            break;
    }
    
    return nil;
}

/**
 验证请求后返回结果的数据

 @param request request description
 @param error error description
 @return return value description
 */
- (BOOL)validateResult:(TYZBaseRequest *)request error:(NSError *_Nullable __autoreleasing *)error
{
    BOOL result = [request statusCodeValidator];
    if (!result)
    {
        NSInteger statusCode = [request responseStatusCode];
        if (error)
        {
//            statusCode >= 200 && statusCode <= 299
            NSString *errStr = [NSString stringWithFormat:@"Invalid status code=%zd", statusCode];
            *error = [NSError errorWithDomain:TYZRequestValidationErrorDomain code:TYZRequestValidationErrorInvalidStatusCode userInfo:@{NSLocalizedDescriptionKey:errStr}];
        }
        return result;
    }
    
    id json = [request responseJSONObject];
    id validator = [request jsonValidator];
    if (json && validator)
    {
        result = [TYZNetworkUtils validateJSON:json withValidator:validator];
        if (!result)
        {
            if (*error)
            {
                *error = [NSError errorWithDomain:TYZRequestValidationErrorDomain code:TYZRequestValidationErrorInvalidJSONFormat userInfo:@{NSLocalizedDescriptionKey:@"Invalid JSON format"}];
            }
        }
        return result;
    }
    
    return YES;
}

/**
 请求后，返回结果

 @param task task
 @param responseObject 返回的数据
 @param error error description
 */
- (void)handleRequestResult:(NSURLSessionTask *)task responseObject:(id)responseObject error:(NSError *)error
{
    pthread_mutex_lock(&_lock);
    TYZBaseRequest *request = _requestsRecord[@(task.taskIdentifier)];
    pthread_mutex_unlock(&_lock);
    
    if (!request)
    {
        return;
    }
    
//    NSLog(@"Finished Request: %@", NSStringFromClass([request class]));
    
    NSError * __autoreleasing serializationError = nil;
    NSError * __autoreleasing validationError = nil;
    
    NSError *requestError = nil;
    BOOL success = NO;
    
    request.responseObject = responseObject;
    
    if ([request.responseObject isKindOfClass:[NSData class]])
    {
        request.responseData = responseObject;
        request.responseString = [[NSString alloc] initWithData:responseObject encoding:[TYZNetworkUtils stringEncodingWithRequest:request]];
        
//        NSLog(@"tb-url=%@; restr=%@", [request requestUrl], request.responseString);
        
        switch (request.responseSerializerType)
        {
            case TYZResponseSerializerTypeHTTP:
            {
                // default serializer. do nothing.
            } break;
            case TYZResponseSerializerTypeJSON:
            {
                request.responseObject = [self.jsonResponseSerializer responseObjectForResponse:task.response data:request.responseData error:&serializationError];
                request.responseJSONObject = request.responseObject;
            } break;
            case TYZResponseSerializerTypeXML:
            {
                request.responseObject = [self.xmlParserResponseSerialzier responseObjectForResponse:task.response data:request.responseData error:&serializationError];
            } break;
            default:
                break;
        }
        
    }
    
    NSString *url = [self buildRequestUrl:request];
//    [[LogManager sharedInstance] logInfo:@"首页" logStr:@"这是日志信息!",@"可以多参数",nil];
//    [[TYZLogManager sharedInstance] logInfo:@"网络请求" logStr:url, nil];
    if (error)
    {// 请求失败
        success = NO;
        requestError = error;
        NSString *errorStr = [NSString stringWithFormat:@"net-请求失败=%@; url=%@", [error localizedDescription], url];
        debugLog(@"%@", errorStr);
    }
    else if (serializationError)
    {// 系列化失败
        success = NO;
        requestError = serializationError;
        NSString *errorStr = [NSString stringWithFormat:@"net-系列化失败=%@; url=%@", [requestError localizedDescription], url];
        debugLog(@"%@", errorStr);
    }
    else
    {// 校验 校验请求回来的json数据跟我们提供的数据字段是否一直
        success = [self validateResult:request error:&validationError];
        requestError = validationError;
        if (validationError)
        {
            NSString *errorStr = [NSString stringWithFormat:@"校验请求回来的json数据跟我们提供的数据字段是否一直=%@; url=%@", [validationError localizedDescription], url];
            debugLog(@"%@", errorStr);
        }
    }
    
    if (success)
    {
        [self requestDidSuccessWithRequest:request];
    }
    else
    {
        [self requestDidFailWithRequest:request error:requestError];
    }
    
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [self removeRequestFromRecord:request];
        [request clearCompletionBlock];
    });
    
}

/**
 成功

 @param request request description
 */
- (void)requestDidSuccessWithRequest:(TYZBaseRequest *)request
{
    //  磁盘缓存
    @autoreleasepool {
        // 请求回调需要做的操作，这里主要就是缓存
        // 请求完成预处理
        [request requestCompletePreprocessor];
    }
    
    [request requestCompleteFilter]; // 可以做进一步处理，然后再回调
    dispatch_async(dispatch_get_main_queue(), ^{
        if (request.successCompletionBlock)
        {
            request.successCompletionBlock(request);
        }
    });
    
}

/**
 失败

 @param request request description
 @param error error description
 */
- (void)requestDidFailWithRequest:(TYZBaseRequest *)request error:(NSError *)error
{
    request.error = error;
    debugLog(@"network-error=%@", [error localizedDescription]);
    // save incomplete download data.
    NSData *incompleteDownloadData = error.userInfo[NSURLSessionDownloadTaskResumeData];
    if (incompleteDownloadData)
    {
        [incompleteDownloadData writeToURL:[self incompleteDownloadTempPathForDownloadPath:request.resumableDownloadPath] atomically:YES];
    }
    
    // load response from file and clean up if download task failed.
    if ([request.responseObject isKindOfClass:[NSURL class]])
    {
        NSURL *url = request.responseObject;
        if (url.isFileURL && [[NSFileManager defaultManager] fileExistsAtPath:url.path])
        {
            request.responseData = [NSData dataWithContentsOfURL:url];
            request.responseString = [[NSString alloc] initWithData:request.responseData encoding:[TYZNetworkUtils stringEncodingWithRequest:request]];
            
            [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
        }
        request.responseObject = nil;
    }
    
    @autoreleasepool {
        [request requestFailedPreprocessor];
    }
    
    [request requestFailedFilter]; // 做进一步处理
    dispatch_async(dispatch_get_main_queue(), ^{
        if (request.failureCompletionBlock)
        {
            request.failureCompletionBlock(request);
        }
    });
    
}

/**
 把请求的request添加到字典中

 @param request request description
 */
- (void)addRequestToRecord:(TYZBaseRequest *)request
{
    pthread_mutex_lock(&_lock);
    _requestsRecord[@(request.requestTask.taskIdentifier)] = request;
    pthread_mutex_unlock(&_lock);
}

/**
 删除请求的requst

 @param request request description
 */
- (void)removeRequestFromRecord:(TYZBaseRequest *)request
{
    pthread_mutex_lock(&_lock);
    [_requestsRecord removeObjectForKey:@(request.requestTask.taskIdentifier)];
    pthread_mutex_unlock(&_lock);
}


/**
 正常的请求数据

 @param method method description
 @param requestSerializer requestSerializer description
 @param URLString URLString description
 @param parameters parameters description
 @param error error description
 @return return value description
 */
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                               requestSerializer:(AFHTTPRequestSerializer *)requestSerializer
                                       URLString:(NSString *)URLString
                                      parameters:(id)parameters
                                           error:(NSError * _Nullable __autoreleasing *)error
{
    return [self dataTaskWithHTTPMethod:method requestSerializer:requestSerializer URLString:URLString parameters:parameters constructingBodyWithBlock:nil error:error];
}

/**
 多表单请求数据

 @param method method description
 @param requestSerializer requestSerializer description
 @param URLString URLString description
 @param parameters parameters description
 @param block block description
 @param error error description
 @return return value description
 */
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                               requestSerializer:(AFHTTPRequestSerializer *)requestSerializer
                                       URLString:(NSString *)URLString
                                      parameters:(id)parameters
                       constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                                           error:(NSError * _Nullable __autoreleasing *)error
{
    NSMutableURLRequest *request = nil;
    
    if (block)
    {
        request = [requestSerializer multipartFormRequestWithMethod:method URLString:URLString parameters:parameters constructingBodyWithBlock:block error:error];
    }
    else
    {
        request = [requestSerializer requestWithMethod:method URLString:URLString parameters:parameters error:error];
    }
    
    __block NSURLSessionDataTask *dataTask = nil;
    dataTask = [_manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
//        NSLog(@"tb-error=%@", [error localizedDescription]);
        [self handleRequestResult:dataTask responseObject:responseObject error:error];
    }];
    
    return dataTask;
}


- (NSURLSessionDownloadTask *)downloadTaskWithDownloadPath:(NSString *)downloadPath
                                         requestSerializer:(AFHTTPRequestSerializer *)requestSerializer
                                                 URLString:(NSString *)URLString
                                                parameters:(id)parameters
                                                  progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                                     error:(NSError * _Nullable __autoreleasing *)error
{
    // add parameters to URL;
    NSMutableURLRequest *urlRequest = [requestSerializer requestWithMethod:@"GET" URLString:URLString parameters:parameters error:error];
    
    NSString *downloadTargetPath;
    BOOL isDirectory;
    if(![[NSFileManager defaultManager] fileExistsAtPath:downloadPath isDirectory:&isDirectory])
    {
        isDirectory = NO;
    }
    // If targetPath is a directory, use the file name we got from the urlRequest.
    // Make sure downloadTargetPath is always a file, not directory.
    if (isDirectory)
    {
        /** 从路径中获得完整的文件名（带后缀） */
        NSString *fileName = [urlRequest.URL lastPathComponent];
        /** 构建完整的下载路径 */
        downloadTargetPath = [NSString pathWithComponents:@[downloadPath, fileName]];
    }
    else
    {
        downloadTargetPath = downloadPath;
    }
    
    // AFN use `moveItemAtURL` to move downloaded file to target path,
    // this method aborts the move attempt if a file already exist at the path.
    // So we remove the exist file before we start the download task.
    // https://github.com/AFNetworking/AFNetworking/issues/3775
    /** AFN 会使用 moveItemAtURL 将下载的文件移动到目标路径，如果文件已经存在则会停止，所以这边下载前先移除已存在文件 */
    if ([[NSFileManager defaultManager] fileExistsAtPath:downloadTargetPath])
    {
        [[NSFileManager defaultManager] removeItemAtPath:downloadTargetPath error:nil];
    }
    
    BOOL resumeDataFileExists = [[NSFileManager defaultManager] fileExistsAtPath:[self incompleteDownloadTempPathForDownloadPath:downloadPath].path];
    NSData *data = [NSData dataWithContentsOfURL:[self incompleteDownloadTempPathForDownloadPath:downloadPath]];
    BOOL resumeDataIsValid = [TYZNetworkUtils validateResumeData:data];
    
    BOOL canBeResumed = resumeDataFileExists && resumeDataIsValid;
    BOOL resumeSucceeded = NO;
    __block NSURLSessionDownloadTask *downloadTask = nil;
    // Try to resume with resumeData.
    // Even though we try to validate the resumeData, this may still fail and raise excecption.
    if (canBeResumed)
    {
        @try {
            downloadTask = [_manager downloadTaskWithResumeData:data progress:downloadProgressBlock destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
                return [NSURL fileURLWithPath:downloadTargetPath isDirectory:NO];
            } completionHandler:
                            ^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                                [self handleRequestResult:downloadTask responseObject:filePath error:error];
                            }];
            resumeSucceeded = YES;
        } @catch (NSException *exception) {
//            YTKLog(@"Resume download failed, reason = %@", exception.reason);
            resumeSucceeded = NO;
        }
    }
    if (!resumeSucceeded) {
        downloadTask = [_manager downloadTaskWithRequest:urlRequest progress:downloadProgressBlock destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            return [NSURL fileURLWithPath:downloadTargetPath isDirectory:NO];
        } completionHandler:
                        ^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                            [self handleRequestResult:downloadTask responseObject:filePath error:error];
                        }];
    }
    return downloadTask;
}


- (NSString *)incompleteDownloadTempCacheFolder
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    static NSString *cacheFolder;
    if (!cacheFolder)
    {
        NSString *cacheDir = NSTemporaryDirectory();
        cacheFolder = [cacheDir stringByAppendingPathComponent:kTYZNetworkIncompleteDownloadFolderName];
    }
    NSError *error = nil;
    if (![fileManager createDirectoryAtPath:cacheFolder withIntermediateDirectories:YES attributes:nil error:&error])
    {
        cacheFolder = nil;
    }
    return cacheFolder;
}

- (NSURL *)incompleteDownloadTempPathForDownloadPath:(NSString *)downloadPath
{
    NSString *tempPath = nil;
    NSString *md5URLString = [TYZNetworkUtils md5StringFromString:downloadPath];
    tempPath = [[self incompleteDownloadTempCacheFolder] stringByAppendingPathComponent:md5URLString];
    return [NSURL fileURLWithPath:tempPath];
}

@end























